/*
 * Fichier définissant le niveau
 */
#ifndef PAC_LEVEL_H
#define PAC_LEVEL_H

#include "lc_array.h"
#include "pac_object.h"
#include "pac_ghost.h"


#define PAC_GUM_CODE 0

#define BLOCK_CODE 1

#define POWER_BALL_CODE 2

#define PACMAN_START 3

#define FENCE_CODE 4

#define GHOST_CODE 5

#define EMPTY_CODE 66

#define ERROR_CODE -66


typedef struct PacLevel PacLevel;

/**
 * Structure permettant de stocker le niveau courant
 */
struct PacLevel {
    // Matrice contenant les objets fixes
    LCarray * map;

    // Liste contenant les fantomes
    LCarray * ghosts;

    // Matrice contenant les PacBalls (PacGums et powerBalls) courantes
    LCarray * pacBalls;

    // Matrice contenant les PacBalls (PacGums et powerBalls) initiales
    LCarray * initialPacBalls;

    // Nombre initial de PacBalls 
    int initialPacBallCount;

    // Le PacMan!
    PacObject* pacMan;

    // Vitesse de déplacement de PacMan (en ms)
    int pacman_speed;

    // Vitesse de déplacement des fantomes (en ms)
    int ghost_normal_speed;

    // Vitesse de déplacement des fantomes (en ms)
    int ghost_vulnerable_speed;

    // Intelligence des fantômes (de 0 à 5, 0 = stupide, 5 = très fort!)
    int ghostIntelligence;

    // Durée des PacPouvoir
    int powerball_duration;

    // Nombre de PacBalls restantes
    int remaining_pacBalls;

};

/**
 * Construit le niveau.
 */
PacLevel* levelCreate();

/**
 * Libère les ressources du niveau.
 * @param level, niveau à libérer.²
 */
void levelFree(PacLevel *level);

/**
 * Assigne la vitesse de PacMan
 * @param aLevel, Niveau à paramétrer.
 * @param aSpeed, Vitesse à assigner (en ms).
 */
void levelSetPacmanSpeed(PacLevel *aLevel, int aSpeed);


/**
 * Assigne la vitesse des fantômes
 * @param aLevel, Niveau à paramétrer.
 * @param aSpeed, Vitesse à assigner (en ms).
 */
void levelSetGhostSpeed(PacLevel *aLevel, int aSpeed);


/**
 * Assigne la durée des PacPouvoirs
 * @param aLevel, Niveau à paramétrer.
 * @param aSpeed, Durée à assigner (en ms).
 */
void levelSetPowerballDuration(PacLevel *aLevel, int aDuration);

/**
 * Retourne la hauteur du niveau passé en paramètre.
 */
int levelGetSizeY(PacLevel *aLevel);

/**
 * Retourne la largeur du niveau passé en paramètre.
 */
int levelGetSizeX(PacLevel *aLevel);

/**
 * Retourne le code d'une case.
 * @param aLevel, Niveau dans lequel rechercher la case.
 * @param posX, Position horizontale de la case.
 * @param posY, Position verticale de la case.
 */
int levelGetCaseAt(PacLevel *aLevel, int posX, int posY);

/**
 *  Retourne le code d'une éventuelle PacBall sur une case.
 * @param aLevel, Niveau dans lequel chercher la PacGum.
 * @param posX, Position horizontale de la case.
 * @param posY, Position verticale de la case.
 */
int levelGetPacBallAt(PacLevel *aLevel, int posX, int posY);

/**
 *  Supprime la PacBall d'une case.
 * @param aLevel, Niveau dans lequel supprimer la PacGum.
 * @param posX, Position horizontale de la case.
 * @param posY, Position verticale de la case.
 */
void removePacBallAt(PacLevel *aLevel, int posX, int posY);

boolean levelCaseIsAccessibleForPacman(PacLevel * aLevel, int aPosX, int aPosY);

boolean levelCaseIsAccessibleForGhost(PacLevel * aLevel, PacGhost * aGhost, int aPosX, int aPosY);

int* levelGetTeleporterTarget(PacLevel *aLevel, int posX, int posY);

#endif /* PAC_LEVEL_H*/
